home *** CD-ROM | disk | FTP | other *** search
- {$V-,S-,I-}
- {$M 16384,0,355360} { leave some memory for PKZIP !!! }
-
-
- { By POPULAR Request .................
- this SIMPLE program let's you read SWAG files and CONVERT them to QWK
- format readable by many of the popular MAIL readers out there. I
- tested it with OLX by MUSTANG. It should would with the others as well.
-
- WARNING ... Many QWK mail readers are limited in the amount of text
- that can be contained in one message. SEVERAL of the SWAG files exceed
- what can be read !! Therefore, you will NOT be able to read all of these.
- Your mail reader program will truncate them. This was an interesting
- exercise anyway, and shows how QWK mail packets can be created.
-
- Gayle Davis
- November, 1993 }
-
- USES
- Dos, Crt;
-
- CONST
- ControlHdr : ARRAY [1..11] OF STRING [30] = (
-
- {1} 'SOURCEWARE ARCHIVAL GROUP',
- {2} 'Goshen',
- {3} '875-8133',
- {4} 'Gayle Davis',
- {5} '99999,SWAG',
- {6} '11-03-1993,04:41:37',
- {7} 'SWAG Genius',
- {8} '', { QMAIL Menu name ??? }
- {9} '0', { allways ZERO ??? }
- {10} '0', { total number of messages in package }
- {11} '56'); { number of conferences-1 here }
- { next is 0 , then first conference }
-
- TYPE
-
- BlockArray = ARRAY [1..128] OF CHAR;
- CharArray = ARRAY [1..6] OF CHAR; { to read in chunks }
- ControlArray = ARRAY [1..200] OF STRING [20];
- bsingle = array [0..4] of byte;
-
- MSGDATHdr = RECORD { ALSO the format for SWAG files !!! }
- Status : CHAR;
- MSGNum : ARRAY [1..7] OF CHAR;
- Date : ARRAY [1..8] OF CHAR;
- Time : ARRAY [1..5] OF CHAR;
- UpTO : ARRAY [1..25] OF CHAR;
- UpFROM : ARRAY [1..25] OF CHAR;
- Subject : ARRAY [1..25] OF CHAR;
- PassWord : ARRAY [1..12] OF CHAR;
- ReferNum : ARRAY [1..8] OF CHAR;
- NumChunk : CharArray;
- Alive : BYTE;
- LeastSig : BYTE;
- MostSig : BYTE;
- Reserved : ARRAY [1..3] OF CHAR;
- END;
-
- CONST
-
- PKZIP : PathStr = 'PKZIP.EXE';
-
- VAR
-
- SWAGF,
- QWKF : FILE;
- ControlF : TEXT;
-
- SavePath,
- SwagPath,
- SWAGFn,
- MsgFName : PATHSTR;
-
- TR : SearchRec;
-
- ConfNum,
- Number : WORD;
-
- MSGHdr : MSGDatHdr;
- ch : CHAR;
- count : INTEGER;
- chunks : INTEGER;
- ControlVal : ControlArray;
- ControlIdx : BYTE;
- WStr : STRING;
-
- FUNCTION TrimL (InpStr : STRING) : STRING; ASSEMBLER;
- ASM
- PUSH DS
- LDS SI, InpStr
- XOR AX, AX
- LODSB
- XCHG AX, CX
- LES DI, @Result
- INC DI
- JCXZ @@2
-
- MOV BL, ' '
- CLD
- @@1 : LODSB
- CMP AL, BL
- LOOPE @@1
- DEC SI
- INC CX
- REP MOVSB
-
- @@2 : XCHG AX, DI
- MOV DI, WORD PTR @Result
- SUB AX, DI
- DEC AX
- STOSB
- POP DS
- END;
-
- FUNCTION TrimR (InpStr : STRING) : STRING;
-
- VAR i : INTEGER;
-
- BEGIN
- i := LENGTH (InpStr);
- WHILE (i >= 1) AND (InpStr [i] = ' ') DO
- i := i - 1;
- TrimR := COPY (InpStr, 1, i)
- END;
-
- FUNCTION TrimB (InpStr : STRING) : STRING;
-
- BEGIN
- TrimB := TrimL (TrimR (InpStr) );
- END;
-
- FUNCTION IntStr (Num : LONGINT; Width : BYTE; Zeros : BOOLEAN) : STRING;
- { Return a string value (width 'w')for the input integer ('n') }
- VAR
- Stg : STRING;
- BEGIN
- STR (Num : Width, Stg);
- IF Zeros THEN BEGIN
- FOR Num := 1 TO Width DO IF Stg [Num] = #32 THEN Stg [Num] := '0';
- END ELSE Stg := TrimL (Stg);
- IntStr := Stg;
- END;
-
- FUNCTION NameOnly (FileName : PathStr) : PathStr;
- { Strip any path information from a file specification }
- VAR
- Dir : DirStr;
- Name : NameStr;
- Ext : ExtStr;
- BEGIN
- FSplit (FileName, Dir, Name, Ext);
- NameOnly := Name;
- END {NameOnly};
-
- FUNCTION EraseFile ( S : PathStr ) : BOOLEAN ;
- VAR F : FILE;
- BEGIN
- EraseFile := FALSE;
- ASSIGN (F, S);
- RESET (F);
- IF IORESULT <> 0 THEN EXIT;
- CLOSE (F);
- ERASE (F);
- EraseFile := (IORESULT = 0);
- END;
-
- PROCEDURE FindSwagPath (VAR P : PathStr);
- VAR
- S : PathStr;
- BEGIN
- IF SwagPath <> '' THEN S := SwagPath + '\DRIVES.SWG' ELSE
- S := 'DRIVES.SWG';
- S := FSearch (S, GetEnv ('PATH') );
- IF S = '' THEN
- BEGIN
- WriteLn(#7,'You GOTTA have the SWAG files somewhere on your PATH to do this !!');
- WriteLn(#7,'OR, you can enter the path on the command line !!');
- HALT(1);
- END;
- S := FExpand (S);
- P := FExpand (COPY(S,1,POS('DRIVES',S)-1));
- END;
-
- PROCEDURE FindPKZip;
- VAR
- S : PathStr;
- BEGIN
- S := FSearch ('PKZIP.EXE', GetEnv ('PATH') );
- IF S = '' THEN
- BEGIN
- WriteLn(#7,'You GOTTA have PKZIP somewhere on your PATH to do this !!');
- HALT(1);
- END;
- PKZIP := FExpand (S);
- END;
-
- PROCEDURE CleanUp;
- { clean up after ourselves }
- BEGIN
- FINDFIRST ('*.NDX', $21, TR);
- WHILE DosError = 0 DO
- BEGIN
- EraseFile(TR.NAME);
- FINDNEXT (TR);
- END;
- EraseFile('MESSAGES.DAT');
- EraseFile('CONTROL.DAT');
- END;
-
- PROCEDURE CreateControlDat;
- VAR
- I : BYTE;
- BEGIN
- ControlHdr [11] := IntStr (PRED (ConfNum), 3, FALSE);
- ASSIGN (ControlF, 'CONTROL.DAT');
- REWRITE (ControlF);
- FOR I := 1 TO 11 DO
- WRITELN (ControlF, ControlHdr [i]);
- FOR I := 1 TO ControlIdx DO
- WRITELN (ControlF, ControlVal [i]);
- CLOSE (ControlF);
- END;
-
- PROCEDURE CreateMessageDat;
- VAR
- I : BYTE;
- Buff : BlockArray;
- BEGIN
- FILLCHAR (ControlVal, SIZEOF (ControlVal), #0);
- FILLCHAR (Buff, SIZEOF (Buff), #32);
- FILLCHAR (MsgHdr, SIZEOF (MsgHdr), #32);
- ConfNum := 0;
- ControlIdx := 0;
- Number := 0;
- ASSIGN (QWKF, 'MESSAGES.DAT');
- REWRITE (QWKF, SIZEOF (MsgHdr) );
- WStr := 'SWAG TO QWK (c) 1993 GDSOFT';
- FOR I := 1 TO LENGTH (WStr) DO Buff [i] := WSTR [i];
- BLOCKWRITE (QwkF, Buff, 1);
- END;
-
- FUNCTION ArrayTOInteger (B : CharArray; Len : BYTE) : LONGINT;
-
- VAR I : BYTE;
- S : STRING;
- E : INTEGER;
- T : INTEGER;
-
- BEGIN
- S := '';
- FOR I := 1 TO PRED (Len) DO IF B [i] <> #32 THEN S := S + B [i];
- VAL (S, T, E);
- IF E = 0 THEN ArrayToInteger := T;
- END;
-
- PROCEDURE ReadMessage (HDR : MSGDatHdr; RelNum : LONGINT; VAR Chunks : INTEGER);
- VAR
- Buff : BlockArray;
- J : INTEGER;
- I : BYTE;
- NS : STRING;
-
- BEGIN
-
- { read the header block }
- SEEK (SwagF, RelNum - 1);
- BLOCKREAD (SwagF, Hdr, 1);
-
- { Correct the record number }
- INC(Number);
- NS := IntStr(Number,7,FALSE);
- WHILE Length(NS) < 7 DO NS := NS + #32;
- MOVE (NS, Hdr.MsgNum, 7);
- Hdr.LeastSig := ConfNum;
- Hdr.MostSig := Number;
-
- { write the header to our QWK file }
- BLOCKWRITE (QwkF, Hdr, 1);
-
- { process the rest of the blocks }
- Chunks := ArrayToInteger (HDR.NumChunk, 6);
- FOR J := 1 TO PRED (Chunks) DO
- BEGIN
- BLOCKREAD (SwagF, Buff, 1);
- BLOCKWRITE (QwkF, Buff, 1);
- END;
-
- END;
-
- PROCEDURE ProcessSwag (FN : PathStr);
- VAR
- ndxF : File;
- b : bSingle;
- r : REAL;
- n : LONGINT;
-
- { converts TP real to Microsoft 4 bytes single .. GOOFY !!!! }
- procedure real_to_msb (preal : real; var b : bsingle);
- var
- r : array [0 .. 5] of byte absolute preal;
- begin
- b [3] := r [0];
- move (r [3], b [0], 3);
- end; { procedure real_to_msb }
-
-
- BEGIN
-
- WriteLn('Process .. ',FN);
- { create the NDX file }
- ASSIGN (ndxF,IntStr(ConfNum,3,TRUE)+'.NDX');
- REWRITE (ndxF,1);
-
- ASSIGN (SwagF, FN);
- RESET (SwagF, SIZEOF (MsgHdr) );
- Count := 2; { start at RECORD #2 }
-
- WHILE (Count < FILESIZE (SwagF) ) DO
- BEGIN
-
- n := SUCC(FilePos(QwkF)); { ndx wants the RELATIVE position }
- r := N; { make a REAL }
- REAL_TO_MSB(r,b); { convert to MSB format }
- BLOCKWRITE(ndxF,B,SizeOf(B)); { store it }
-
- ReadMessage (MSGHdr, Count, Chunks);
- INC (Count, Chunks);
- END;
-
- CLOSE (SwagF);
- CLOSE (NdxF);
-
- { update the CONTROL file array }
- INC (ControlIdx);
- ControlVal [ControlIdx] := IntStr (ConfNum, 3, TRUE);
- INC (ControlIdx);
- ControlVal [ControlIdx] := NameOnly (FN);
- INC (ConfNum);
-
- END;
-
-
- BEGIN
-
- ClrScr;
-
- IF ParamCount > 0 THEN SwagPath := FExpand(ParamStr(1));
-
- EraseFile('SWAG.QWK'); { make sure we don't have one yet }
-
- FindSwagPath (SwagPath);
-
- FindPkZip;
-
- CreateMessageDat;
-
- IF SwagPath [LENGTH (SwagPath) ] <> '\' THEN SwagPath := SwagPath + '\';
-
- FINDFIRST (SwagPath + '*.SWG', $21, TR);
- WHILE DosError = 0 DO
- BEGIN
- ProcessSwag (SwagPath + TR.Name);
- FINDNEXT (TR);
- END;
-
- CLOSE (QwkF);
-
- CreateControlDat;
-
- SwapVectors;
- Exec(PKZIP,' -ex SWAG.QWK *.NDX MESSAGES.DAT CONTROL.DAT');
- SwapVectors;
-
- CleanUp;
-
- END.